#include <iostream>
#include<string>
using namespace std;

//
//int main()
//{
//    int i = 11;
//    double d = i;   //中间就会产生临时变量
//    const double& rd = i;//这就没有临时变量
//
//
//
//    return 0;
//}

//class Person
//{
//public:
//    Person(const char* name = "peter")
//        : _name(name)
//    {
//        cout << "Person()" << endl;
//    }
//
//    Person(const Person& p)
//        : _name(p._name)
//    {
//        cout << "Person(const Person& p)" << endl;
//    }
//
//    Person& operator=(const Person & p)
//    {
//        cout << "Person operator=(const Person& p)" << endl;
//        if (this != &p)
//            _name = p._name;
//
//        return *this;
//    }
//
//    ~Person()
//    {
//        cout << "~Person()" << endl;
//    }
//protected:
//    string _name; // 姓名
//};
//
//class Student : public Person
//{
//public:
//    Student(const char* name, int num)
//        : Person(name)
//        , _num(num)
//    {
//        cout << "Student()" << endl;
//    }
//
//    Student(const Student& s)
//        : Person(s)
//        , _num(s._num)
//    {
//        cout << "Student(const Student& s)" << endl;
//    }
//
//    Student& operator = (const Student& s)
//    {
//        cout << "Student& operator= (const Student& s)" << endl;
//        if (this != &s)
//        {
//            Person::operator =(s);
//            _num = s._num;
//        }
//        return *this;
//    }
//    //第一怪：1、子类析构函数和父类析构函数构成隐藏/重定义关系。（由于多态的关系需求，所有的析构函数都会被处理成相同的析构函数：destructor）
//    //父类的析构在子类的析构函数之后
//    //第二怪：子类先析构，父类在析构，派生类析构函数不需要显示调用父类析构，子类析构后会自动调用父类析构
//    ~Student()
//    {
//        //调用父类的析构函数
//       // Person::~Person();
//        cout << "~Student()" << endl;
//    }
//protected:
//    int _num; //学号
//};
//
//int main()
//{
//
//    Student s("zhangsan",10);
//    return 0;
//    
//}




////友元关系不继承
//class Student;
//class Person
//{
//public:
//	friend void Display(const Person& p, const Student& s);
//protected:
//	string _name; // 姓名
//};
//class Student : public Person
//{
//	friend void Display(const Person& p, const Student& s);//同时变成子类的友元  能不用友元就不用友元
//protected:
//	int _stuNum; // 学号
//};
//void Display(const Person& p, const Student& s)
//{
//	cout << p._name << endl;
//	cout << s._stuNum << endl;  //访问不了
//}
//int main()
//{
//	Person p;
//	Student s;
//	Display(p, s);
//	return 0;
//}




//
////基类定义了static静态成员，则整个继承体系里面只有一个这样的成员。无论派生出多少个子
////类，都只有一个static成员实例 ，也就是父类跟子类的static指向同一块儿地址
////静态成员属于整个类，所有对象，同时也属于所有派生类及对象
//class Person
//{
//public:
//	Person() { ++_count; }
//	string _name; // 姓名
//	void Print()
//	{
//		cout << this << endl;
//		cout << _name << endl;  //会报错
//		cout << _count << endl;//不会报错
//	}
//public:
//	static int _count; // 统计人的个数。
//};
//int Person::_count = 0;
//class Student : public Person
//{
//protected:
//	int _stuNum; // 学号
//};
//
//int main()
//{
//	Person p;
//	Student s;
//	s._name = "lisan";
//	p._name = "张三";
//	s._count++;
//	p._count++;
//	cout << p._count << endl;
//	cout << s._count << endl;
//	cout << &s._count << endl;
//	cout << &p._count << endl;
//
//
//	Person* ptr = nullptr;
//	//cout << ptr->_name << endl;  //NO ，这是解引用，name在Ptr对象里面
//	ptr->Print();                 //可以调  对象里面只存成员对象
//	cout << ptr->_count << endl;  //YES 静态成员在静态区，不在成员变量里面
//
//
//	(*ptr).Print();                //ok,ptr只是起一个传递this指针的作用，这个*也不会去解引用，在编译之后，函数在代码段
//	cout << (*ptr)._count << endl;    //ok
//
//	return 0;
//
//}


//class Person
//{
//public:
//	string _name; // 姓名
//};
//class Student : public Person
//{
//protected:
//	int _num; //学号
//};
//class Teacher : public Person
//{
//protected:
//	int _id; // 职工编号
//};
//class Assistant : public Student, public Teacher
//{
//protected:
//	string _majorCourse; // 主修课程
//};
//int main()
//{
//	Assistant a;
//	//a._name;  //造成二义性/数据冗余
//	//二义性可以指定作用域
//	//可以采用虚继承 virtual
//
//	return 0;
//
//}


//class Person
//{
//public:
//	string _name; // 姓名
//};
//class Student : virtual public Person
//{
//protected:
//	int _num; //学号
//};
//class Teacher : virtual public Person
//{
//protected:
//	int _id; // 职工编号
//};
//class Assistant : public Student, public Teacher
//{
//protected:
//	string _majorCourse; // 主修课程
//};
//int main()
//{
//	Assistant a;
//	a._name = "张三";
//
//	return 0;
//
//}



class A
{
public:
	int _a;
};
// class B : public A
class B : virtual public A
{
public:
	int _b;
};
// class C : public A
class C : virtual public A
{
public:
	int _c;
};
class D : public B, public C
{
public:
	int _d;
};


int main()
{
	D d;
	d._b = 1;
	d._c = 2;
	d._d = 3;
	d.B::_a = 4;
	d.C::_a = 5;
	d._a = 6;

	B b;
	b._a = 1;
	b._b = 2;
	B* ptr = &b;
	ptr->_a = 10;

	ptr = &d;
	ptr->_a = 20;


	return 0;
}
